package com.panopset.gui;

import java.awt.Component;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.net.URI;
import java.util.Date;
import java.util.List;

import javax.swing.JDialog;
import javax.swing.JFrame;

import com.panopset.Util;
import java.util.ArrayList;

/**
 * Usually used for about boxes, a PopupBox is a modeless dialog that disappears
 * when the user does a mouse click or presses any key.
 * @author Karl Dinwiddie
 */
public class PopupBox {

    private final Dimension sz;

    /**
     *Parent frame.
     */
    private JFrame parent;

    /**
     *Internal component.
     */
    private final Component component;

    /**
     *Links.
     */
    private final List<Link> links = new ArrayList<Link>();

    /**
     *@param innerComponent
     *           to display
     */
    public PopupBox(final Component innerComponent, Dimension size,
            final JFrame parentFrame) {
        component = innerComponent;
        sz = size;
        parent = parentFrame;
    }
    /**
     *Add a link to the display area.
     *
     *@param area
     *           Area where link will be hot.
     *@param urlString
     *           URL as String.
     */
    public final void addLink(final Rectangle area, final String urlString) {
        links.add(new Link(area, urlString));
    }

    /**
     *Dispose popup box.
     */
    public final void dispose() {
        if (dialog != null) {
            dialog.dispose();
            dialog = null;
        }
    }

    /**
     *Show popup box.
     */
    public final void show() {
        getDialog().setVisible(true);
    }

    /**
     *Popup box dialog.
     */
    private JDialog dialog;

    private static long LAST_CLICK_TIME = 0;

    /**
     *@return Popup box dialog.
     */
    private JDialog getDialog() {
        if (dialog == null) {
            dialog = new JDialog();
            dialog.setUndecorated(true);
            dialog.setSize(sz);
            if (parent != null) {
                dialog.setLocation(Util.centerInRect(dialog.getSize(), parent
                        .getBounds())); // parent = getFlexFrame().getFrame()
            }
            dialog.add(component);
            dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            component.addKeyListener(new KeyAdapter() {

                @Override
                public void keyPressed(final KeyEvent e) {
                    PopupBox.this.dispose();
                }

            });
            component.addMouseListener(new MouseAdapter() {

                @Override
                public void mousePressed(final MouseEvent e) {
                    for (Link link : links) {
                        if (Util.pointInRect(e.getPoint(), link.getArea())) {
                            return;
                        }
                    }
                    PopupBox.this.dispose();
                }

                @Override
                public void mouseClicked(final MouseEvent e) {
                    for (Link link : links) {
                        if (Util.pointInRect(e.getPoint(), link.getArea())) {
                            try {
                                synchronized(this) {
                                    long time = new Date().getTime();
                                    if (time - LAST_CLICK_TIME > 500) {
                                        Desktop.getDesktop().browse(
                                                new URI(link.getUrl()));
                                    }
                                    LAST_CLICK_TIME = time;
                                }
                                return;
                            } catch (Exception e1) {
                                Util.log(e1);
                            }
                        }
                    }
                    PopupBox.this.dispose();
                }

            });
            component.addMouseMotionListener(new MouseMotionAdapter() {

                @Override
                public void mouseMoved(final MouseEvent e) {
                    for (Link link : links) {
                        if (Util.pointInRect(e.getPoint(), link.getArea())) {
                             component.setCursor(Cursor
                                    .getPredefinedCursor(Cursor.HAND_CURSOR));
                             return;
                        }
                    }
                    component.setCursor(Cursor
                            .getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                }

            });
        }
        return dialog;
    }
}
